package cate.game.role.mall;

import cate.common.table.d.GDMall;
import cate.common.table.mall.row.MallBaseRow;
import cate.common.table.mall.row.MallItemsRow;
import cate.common.table.mall.row.TreasureHouseItemRow;
import cate.common.util.GameResult;
import cate.game.res.MixRes;
import cate.game.res.MixResIo;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RolePart;
import cate.game.role.bag.vo.UidNumVO;
import cate.game.role.farm.tower.Tower;
import cate.game.role.mall.msg.MyMallDataResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import easy.java.struct.ref.IntRef;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Document("role_mall")
public class RoleMall extends RolePart {
    @NoteField(value = "商店列表")
    public List<Mall> list;

    public RoleMall(){}

    public RoleMall(Role role){
        super(role);
    }

    @Override
    public void initialize(Role role){
        super.initialize(role);
        if (list == null) {
            list = new ArrayList<>();
        }
        // 判断商店是否被关闭或者删除
        Iterator<Mall> it = list.iterator();
        while (it.hasNext()) {
            Mall mall = it.next();
            MallBaseRow row = role.getGame().table.mall.base.get(mall.id);
            if (row == null || !row.enable) {
                it.remove();
                continue;
            }
            mall.initialize(role);
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        for (Mall mall : list) {
            mall.onDaySpan();
        }
        if(!silence){
            noticeUpdate();
        }
    }

    /** 获取单个商店信息 */
    @JsonIgnore
    public GameResult<Mall> getMall(int mallId) {
        GameResult<Mall> r = new GameResult<>();
        for (Mall po : list) {
            if (po.id == mallId) {
                r.data = po;
                return r;
            }
        }
        MallBaseRow row = role.getGame().table.mall.base.get(mallId);
        if (row == null || !row.enable) {
            r.fail("商店不存在或者已经关闭");
            return r;
        }
        Mall mall = new Mall(role, mallId);
        mall.initialize(role);
        list.add(mall);
        r.data = mall;
        return r;
    }

    /** 商店刷新 */
    public GameResult<Mall> refreshMall(int mallId, int refreshType) {
        GameResult<Mall> r = getMall(mallId);
        if (!r.ok()) {
            return r;
        }
        Mall mall = r.data;
        mall.checkRefreshTime();
        MallBaseRow row = mall.getRow();

        switch (refreshType) {
            case GDMall.RefreshType.T0:
                break;
            case GDMall.RefreshType.T1:
                if (mall.hasFreeTimes()) {
                    if (row.freeTimeMax != -1) {
                        mall.costFreeTimes();
                    }
                }else{
                    int maxTime = row.payTimeMax;
                    if(mallId == GDMall.TREASHURE_SHOP_ID){
                        maxTime = role.getGame().table.vip.base.getByLevel(role.getBase().vip).mallRefreshTimes;
                    }
                    EcResult<Void> replaceItemCheckRes = replaceItemCheck(role, row);
                    if (!replaceItemCheckRes.ok() && !mall.hasPayTimes() && maxTime >= 0) {
                        return r.fail("有偿刷新次数不足");
                    }
                    // 检查消耗资源
                    EcResult<Boolean> r1 = refreshConsume(role,row);
                    if (!r1.ok()) {
                        return r.fail(r1.message);
                    }
                    boolean useReplaceItem = r1.data;

                    if (row.payTimeMax != -1 && !useReplaceItem) {
                        mall.costPayTimes();
                    }
                }
                mall.refreshItems();

                if (mallId == GDMall.TREASHURE_SHOP_ID) {
                    role.getHistory().action.mallRefreshTime(GDMall.TREASHURE_SHOP_ID);
                    role.getHistory().action.treasureMallRefresh();
                } else if (mallId == GDMall.TALENT_SHOP_ID) {
                    role.getHistory().action.mallRefreshTime(GDMall.TALENT_SHOP_ID);
                    role.getHistory().action.talentMallRefresh();
                }
                break;
            default:
                return r.fail("商店刷新类型有误");
        }
        // 通知前端最新的商店信息
        mall.noticeUpdate();
        return r.success();
    }

    /**
     *
     * @param role
     * @param row
     * @return 是否使用替代道具
     */
    private GameResult<Void> replaceItemCheck(Role role,MallBaseRow row){
        GameResult<Void> r = new GameResult<>();
        GameResult<MixResItem> consumeRes;
        //优先使用替代道具
        if(StringUtils.isNotBlank(row.replaceCfg)){
            consumeRes = new MixRes(row.replaceCfg).consumeCheck(role, null);
            if(consumeRes.ok()){
                return r.success();
            }
        }
        return r.fail("");
    }

    /**
     *
     * @param role
     * @param row
     *
     * @return 是否使用替代道具
     */
    private GameResult<Boolean> refreshConsume(Role role, MallBaseRow row){
        GameResult<Boolean> r = new GameResult<>();
        GameResult<MixResItem> consumeRes;
        MixRes cRes;
        //优先使用替代道具
        if(StringUtils.isNotBlank(row.replaceCfg)){
            cRes = new MixRes(row.replaceCfg);
            consumeRes = cRes.consume(role, null);
            if(consumeRes.ok()){
                r.data = true;
                return r.success();
            }
        }
        cRes = new MixRes(row.consumeCfg);
        consumeRes = cRes.consume(role, null);
        r.code = consumeRes.code;
        r.message = consumeRes.message;
        r.data = false;
        return r;
    }

    public GameResult<Void> buyItems(int mallId, List<UidNumVO> items) {
        GameResult<Void> r = new GameResult<>();
        if (CollectionUtils.isEmpty(items)) {
            return r.fail("购买商品不存在");
        }
        MixRes reward = new MixRes();
        for (UidNumVO vo : items) {
            GameResult<MixResIo> rewardRes = buyItem(mallId, vo.uid, vo.num, true, false, null);
            if (rewardRes.ok()) {
                reward.addList(rewardRes.data.out());
            }
        }
        if (reward.isEmpty()) {
            return r.fail("购买商品不存在");
        }
        role.getGame().notice.dialogReward(role, reward);
        GameResult<Mall> rData = getMall(mallId);
        if (!rData.ok()) {
            return r.fail(rData.message);
        }
        rData.data.noticeUpdate();
        return r;
    }

    /** 商城道具购买 */
    public GameResult<MixResIo> buyItem(int mallId, String uid, int num, IntRef mallItemIdFill) {
        return buyItem(mallId, uid, num, false, true, mallItemIdFill);
    }

    /** 商城道具购买 */
    public GameResult<MixResIo> buyItem(int mallId, String uid, int num, boolean noRewardDialog, boolean notice, IntRef mallItemIdFill) {
        GameResult<MixResIo> r = new GameResult<>();
        GameResult<Mall> rData = getMall(mallId);
        if (!rData.ok()) {
            return r.fail(rData.message);
        }
        Mall mall = rData.data;
        MallItem item = mall.getItem(uid);
        // 检查购买资格
        GameResult<Void> res = checQualification(mallId, item, num);
        if (!res.ok()) {
            return r.fail(res.message);
        }
        MallItemsRow row = item.getRow();
        if(row != null && mallItemIdFill != null) {
            mallItemIdFill.v = row.id;
        }

        // 本次购物的总花费
        MixRes consume = new MixRes();
        consume.addList(new MixRes(row.consumeConfig).multiply(num));
        // 本次购物的总奖励
        MixRes reward = new MixRes();
        reward.addList(new MixRes(row.itemConfig).multiply(num));

        // 执行扣费，发放奖励
        res = basicBuy(consume, reward);
        if (!res.ok()) {
            return r.fail(res.message);
        }
        if(!noRewardDialog){
            role.getGame().notice.dialogReward(role, reward);
        }
        // 记录商品购买次数
        item.purchaseNum += num;

        // 售罄刷新(针对英雄商店的逻辑)
        if (mall.getRow().refreshAfterSale) {
            checkSoldOut(mall);
        }
        // 商店信息更新
        if (notice) {
            mall.noticeUpdate();
        }
        role.getHistory().action.mallBuyItem(mallId, num);
        role.getHistory().action.itemBuy(row.id, num);
        r.data = MixResIo.build(consume, reward);
        return r;
    }

    /** 商城购买资格检查 */
    private GameResult<Void> checQualification(int mallId, MallItem item, int num) {
        GameResult<Void> r = new GameResult<>();
        if (item == null) {
            return r.fail("商品不存在");
        }
        MallItemsRow row = item.getRow();
        if (row == null) {
            return r.fail("商城表配置错误");
        }
        // 检查购买次数
        if (num <= 0 || row.limitNum > 0 && num > row.limitNum - item.purchaseNum) {
            return r.fail("购买数量有误");
        }
        // VIP等级验证
        if (role.getBase().vip < row.vipRequired) {
            return r.fail(String.format("vip%d以上才能购买", row.vipRequired));
        }
        int openDay = role.getGame().getOpenDay();
        if (mallId != GDMall.TREASHURE_SHOP_ID) {
            // 主角等级验证
            if (row.levelMin != null && role.getBase().level < row.levelMin) {
                return r.fail(String.format("%d级以上才能购买", row.levelMin));
            }
            // 主角等级验证
            if (row.levelMax != null && role.getBase().level > row.levelMax) {
                return r.fail(String.format("%d级以下才能购买", row.levelMax));
            }
            if (row.openDay > 0 && row.openDay > openDay) {
                return r.fail(String.format("开服%d天以后才能购买", row.openDay));
            }
            String res = meetTowerCondition(row.towerConditionStr);
            if (StringUtils.isNotBlank(res)) {
                return r.fail(String.format("通关缚灵之塔%d层才能购买", Integer.parseInt(res.split(":")[1])));
            }
            if (row.endlessCondition > 0 && role.getFarm().endless.combatNumPassed < row.endlessCondition) {
                return r.fail(String.format("通关无尽试炼%d关才能购买", row.endlessCondition));
            }
            if (row.adventureCondition > 0 && role.getFarm().adventure.combatIdPassed < row.adventureCondition) {
                return r.fail(String.format("通关主线%d关才能购买", row.adventureCondition));
            }
        } else {
            TreasureHouseItemRow itemRow = role.getGame().table.mall.treasure.getItemRows(item.tid);
            if (itemRow == null) {
                return r.fail("商品不存在");
            }
            if (role.getBase().level < itemRow.levelMin) {
                return r.fail(String.format("%d级以上才能购买", row.levelMin));
            }
            // 主角等级验证
            if (role.getBase().level > itemRow.levelMax) {
                return r.fail(String.format("%d级以下才能购买", row.levelMax));
            }
            if ((itemRow.opendayMin > 0 && openDay < itemRow.opendayMin) || (itemRow.opendayMax > 0 && openDay > itemRow.opendayMax)) {
                return r.fail("开服天数在{}~{}期间才可购买次物品", itemRow.opendayMin, itemRow.opendayMax);
            }
        }
        return r.success();
    }

    private String meetTowerCondition(String towerConditionStr){
        if (StringUtils.isBlank(towerConditionStr)) {
            return null;
        }
        String[] conditionStrs = towerConditionStr.split("#");
        for (String conditionStr : conditionStrs) {
            String[] conditionArr = conditionStr.split(":");
            Tower tower = role.getFarm().tower;
            if (tower == null) {
                continue;
            }
            if (tower.passedFloor < Integer.parseInt(conditionArr[0])) {
                return conditionStr;
            }
        }
        return null;
    }

    /** 售罄刷新 */
    private void checkSoldOut(Mall mall) {
        for (MallItem item : mall.itemList) {
            int limitNum = item.getRow().limitNum;
            if (limitNum == -1 || item.purchaseNum < limitNum) {
                return;
            }
        }
        // 如果所有商品都购买完则刷新一次商店
        mall.refreshItems();
    }

    /** 基本购买逻辑 */
    public GameResult<Void> basicBuy(MixRes consume, MixRes reward) {
        GameResult<Void> r = new GameResult<>();
        if (reward == null || reward.items == null) {
            r.fail("奖励配置错误");
            return r;
        }
        // 看看钱够不够
        if (consume != null && consume.items != null) {
            EcResult<MixResItem> consumeRes = consume.consumeCheck(role, null);
            if (!consumeRes.ok()) {
                role.getGame().notice.tipResItem(role, consumeRes.data);
                return r.fail(consumeRes);
            }
        }
        // 看看格子够不够
        r = reward.addCheck(role);
        if (!r.ok()) {
            return r;
        }
        // 通过验证,扣除资源,添加物品！
        if (consume != null && consume.items != null) {
            consume.consumeDirect(role, null);
        }
        reward.add(role);
        return r.success();
    }

    public void noticeUpdate() {
        role.sendNow(new MyMallDataResp(role));
    }
}
